package io.github.yidasanqian.content.service.impl;

import io.github.yidasanqian.content.service.ContentCategoryService;
import io.github.yidasanqian.domain.ContentCategory;
import io.github.yidasanqian.dto.ContentCategoryDTO;
import io.github.yidasanqian.mapper.ContentCategoryMapper;
import io.github.yidasanqian.vo.ContentCategoryVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Linyu Chen
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class ContentCategoryServiceImpl implements ContentCategoryService {

    @Resource
    private ContentCategoryMapper contentCategoryMapper;

    @Override
    public int addContentCategoryNode(long parentId, String name) {
        ContentCategory category = new ContentCategory();
        Date date = new Date();
        category.setParentId(parentId);
        category.setName(name);
        category.setStatus(1);
        category.setIsParent(false);
        category.setSortOrder(1);
        category.setCreated(date);
        category.setUpdated(date);
        contentCategoryMapper.insert(category);
        // 添加一个节点需要判断父节点是不是叶子节点，如果父节点是叶子节点的话，需要改成父节点状态
        ContentCategory parentNode = contentCategoryMapper.selectByPrimaryKey(parentId);
        if (!parentNode.getIsParent()) {
            parentNode.setIsParent(true);
            contentCategoryMapper.updateByPrimaryKey(parentNode);
        }

        return 1;
    }

    @Override
    public int deleteContentCategoryNode(long id) {
        ContentCategory category = contentCategoryMapper.selectByPrimaryKey(id);
        category.setStatus(2);
        contentCategoryMapper.updateByPrimaryKey(category);
        // 判断要删除的这个节点是否是父节点，如果是父节点，那么就递归删除这个父节点下的所有子节点
        if (category.getIsParent()) {
            deleteAllChildrenNode(id);
        }

        // 判断一下要删除的这个节点是否是父节点，如果是父节点，那么就级联删除这个父节点下的所有子节点（采用递归的方式删除）
        ContentCategory parentNode = contentCategoryMapper.selectByPrimaryKey(category.getParentId());
        List<ContentCategory> categoryList = contentCategoryMapper.selectAllByParentId(parentNode.getId());
        // 判断父节点是否有子节点是判断这个父节点下的所有子节点的状态，如果状态都是2就说明没有子节点了，否则就是有子节点。
        boolean isExist = false;
        for (ContentCategory contentCategory : categoryList) {
            if (contentCategory.getStatus() == 0) {
                isExist = true;
                break;
            }
        }

        if (!isExist) {
            parentNode.setIsParent(false);
            contentCategoryMapper.updateByPrimaryKey(parentNode);
        }

        return 1;
    }

    private void deleteAllChildrenNode(long parentId) {
        List<ContentCategory> contentCategoryList = contentCategoryMapper.selectAllByParentId(parentId);
        for (ContentCategory category : contentCategoryList) {
            category.setStatus(2);
            contentCategoryMapper.updateByPrimaryKey(category);
            if (category.getIsParent()) {
                deleteAllChildrenNode(category.getId());
            }
        }
    }

    @Override
    public int updateContentCategoryNode(long id, String name) {
        ContentCategory category = contentCategoryMapper.selectByPrimaryKey(id);
        // 判断新的name值与原来的值是否相同，如果相同则不用更新
        if (name != null && name.equals(category.getName())) {
            return 0;
        }

        category.setName(name);
        // 设置更新时间
        category.setUpdated(new Date());
        // 更新数据库
        return contentCategoryMapper.updateByPrimaryKeySelective(category);
    }

    @Override
    public ContentCategoryDTO queryContentCategoryNodeList(long parentId) {
        List<ContentCategory> contentCategoryList = contentCategoryMapper.selectAllByParentId(parentId);
        List<ContentCategoryVO> contentCategoryVOList = new ArrayList<>();
        for (ContentCategory contentCategory : contentCategoryList) {
            ContentCategoryVO categoryVO = new ContentCategoryVO();
            categoryVO.setId(contentCategory.getId());
            categoryVO.setText(contentCategory.getName());
            categoryVO.setIsParent(contentCategory.getIsParent());
            contentCategoryVOList.add(categoryVO);
        }
        ContentCategoryDTO categoryDTO = new ContentCategoryDTO();
        categoryDTO.setContentCategoryVOList(contentCategoryVOList);
        return categoryDTO;
    }
}
